'''
* This is the projet for Brtc LlmOps Platform
* @Author Leon-liao <liaosiliang@alltman.com>
* @Description //TODO 
* @File: with_unsupport_functioncall.py
* @Time: 2025/11/21
* @All Rights Reserve By Brtc
'''
from typing import Type, Any, TypedDict, Dict, Optional
import dotenv
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough, RunnableConfig
from langchain_openai import ChatOpenAI

from mcp_core.mcp_client import MCPClient
from mcp_core.mcp_protocol import StatusCode

dotenv.load_dotenv()

class ToolCallRequest(TypedDict):
    """工具调用字典"""
    name: str
    arguments: Dict[str, any]


with MCPClient(host='127.0.0.1', port=8080) as client:
    #1、获取所有函数列表
    response = client.list_tools()
    if response.status_code == StatusCode.SUCCESS.value:
        tools = response.data["tools"]
    else:
        exit(0)

    def invoke_tool(tool_call_request: ToolCallRequest, config: Optional[RunnableConfig] = None) -> Any:
        """
        我们可使用的执行工具调用函数
        :param tool_call_request: 一个包含函数名和参数的字典, 名称必须与现有函数保持一致，参数是该函数的参数
        :param config:  Langchain使用的 回调参数配置信息
        :return: 返回工具调用信息
        """
        name = tool_call_request["name"]
        print("工具调用:", name)
        print("调用参数:", tool_call_request["arguments"])
        return client.call_tool(name, tool_call_request["arguments"]).data["result"]

    system_prompt = """ 
    您是一个由OpenAI开发的聊天机器人，可以访问以下一组工具。
    以下是每个工具的名称和描述：
    
    {rendered_tools}
    
    根据用户输入，返回要使用的工具的名称和输入。
    将您的响应作为具有`name`和`arguments`键的JSON块返回。
    `arguments`应该是一个字典，其中键对应于参数名称，值对应与请求的值。
    """
    prompt = ChatPromptTemplate.from_messages([
        ("system", system_prompt),
        ("human", "{query}")
    ]).partial(rendered_tools=tools)

    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

    chain = (
            {"query": RunnablePassthrough()}
            | prompt
            | llm
            | JsonOutputParser()
            | RunnablePassthrough.assign(output=invoke_tool)
    )

    print(chain.invoke("hello world!!转换成大写。"))




